#pragma once

#include <iostream>
#include <memory>
#include <set>
#include <vector>
#include <mutex>
#include <event2/bufferevent.h>
#include <event2/buffer.h>
#include <event2/listener.h>
#include <event2/util.h>
#include <event2/event.h>
#include "../inc/appaddress.h"
#include "../core/msgdecoder.h"
#include "../websocket/websocket_handler.h"
#include "httpmsg.h"

using namespace std;

struct SockInfo
{
	evutil_socket_t sock;
	char ip[16];
	unsigned short port;
};

enum Protocol
{
	P_NONE = 0,
	P_SOCKET = 1,
	P_WEBSOCKET = 2,
	P_HTTP = 3,
};

class Connection
{
private:
	evutil_socket_t mSock;
	Websocket_Handler *wsHandler;
	HttpMsgParser *httpParser;
	unsigned int serialNum;
	map<unsigned int, HttpRequest*> mapRequest;
	Protocol protocol_;
	SockInfo sockInfo;
	struct bufferevent * bev;
	MsgDecoder* decoder;
	AppAddress mAddr;
	bool stoped;
	std::mutex  mutexStop;
	struct evbuffer *evbufSend;
	struct evbuffer *evbufWebsocket;
	std::mutex  mutexSend;
public:
	Connection(event_base* base, const SockInfo& sockinfo,int buffersize,int timeout);
	~Connection();

	void sendMsg(const string& msg);
	void executeSend(void* arg);
	void close();
	void setAddress(AppAddress address){ mAddr = address; }
	Protocol protocol() { return protocol_; }
	void set_protocol(Protocol protocol) { protocol_ = protocol; }
public:
	void read();
	void error(short err);
	std::function<void(PackagePtr)> onPackage;
	std::function<void(bool,void*)> onSend;
	std::function<void(short)> onError;
};

typedef std::shared_ptr<Connection> ConnectionPtr;
